home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
UUPC11QS.ARJ
/
DCPSYS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-07
|
21KB
|
661 lines
/*
For best results in visual layout while viewing this file, set
tab stops to every 4 columns.
*/
/*
dcpsys.c
Revised edition of dcp
Stuart Lynne May/87
Copyright (c) Richard H. Lamb 1985, 1986, 1987
Changes Copyright (c) Stuart Lynne 1987
Changes Copyright (c) Andrew H. Derbyshire 1989, 1990
Updated:
13May89 - Modified checkname to only examine first token of name.
Modified rmsg to initialize input character before use.
- ahd
16May89 - Moved checkname to router.c - ahd
17May89 - Wrote real checktime() - ahd
17May89 - Changed getsystem to return 'I' instead of 'G'
25Jun89 - Added Reach-Out America to keyword table for checktime
22Sep89 - Password file support for hosts
25Sep89 - Change 'ExpectStr' message to debuglevel 2
01Jan90 - Revert 'ExpectStr' message to debuglevel 1
28Jan90 - Alter callup() to use table driven modem driver.
Add direct(), qx() procedures.
8 Jul90 - Add John DuBois's expectstr() routine to fix problems
with long input buffers.
11Nov90 - Delete QX support, add ddelay, ssleep calls
*/
/* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
/* Support routines */
/*--------------------------------------------------------------------*/
/* system include files */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <assert.h> /* ahd */
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "arpadate.h"
#include "checktim.h"
#include "dcp.h"
#include "dcpfpkt.h"
#include "dcpgpkt.h"
#include "dcplib.h"
#include "dcpsys.h"
#include "hlib.h"
#include "hostable.h"
#include "modem.h"
#include "nbstime.h"
#include "ndir.h"
#include "security.h"
#include "ulib.h"
currentfile();
#define PROTOS "gf" /* available protocols */
#define MSGTIME 20 /* Timeout for many operations */
Proto Protolst[] = {
'g', ggetpkt, gsendpkt, gopenpk, gclosepk,
grdmsg, gwrmsg, geofpkt, gfilepkt,
'f', fgetpkt, fsendpkt, fopenpk, fclosepk,
frdmsg, fwrmsg, feofpkt, ffilepkt,
'\0'};
procref getpkt, sendpkt, openpk, closepk, rdmsg, wrmsg, eofpkt, filepkt;
char *flds[60];
int kflds;
static char protocols[5];
static char S_sysline[BUFSIZ];
static void setproto(char wanted);
/****************************************/
/* Sub Systems */
/****************************************/
/*--------------------------------------------------------------------*/
/* g e t s y s t e m */
/* */
/* Process a systems file (L.sys) entry. */
/* Null lines or lines starting with '#' are comments. */
/*--------------------------------------------------------------------*/
CONN_STATE getsystem()
{
do { /* flush to next non-comment line */
if (fgets(S_sysline, BUFSIZ, fsys) == nil(char))
return CONN_EXIT;
} while ((*S_sysline == '\0') || (*S_sysline == '\n') || (*S_sysline == '#'));
printmsg(8, "sysline=\"%s\"", S_sysline);
kflds = getargs(S_sysline, flds);
strcpy(rmtname, flds[FLD_REMOTE]);
strcpy(protocols, flds[FLD_PROTO]);
if (debuglevel >= 4) {
int i;
for (i = FLD_EXPECT; i < kflds; i += 2)
printmsg(6, "expect [%02d]:\t%s\nsend [%02d]:\t%s",
i, flds[i], i + 1, flds[i + 1]);
}
printmsg(2,
"remote=%s, call-time=%s, device=%s, telephone=%s, protocol=%s",
rmtname, flds[FLD_CCTIME], flds[FLD_TYPE], flds[FLD_PHONE],
protocols);
fwork = nil(FILE);
if (
!calledhost(rmtname) &&
(
equal(Rmtname, "all") ||
equal(Rmtname, rmtname) ||
(
equal(Rmtname, "any") && (scandir(rmtname) == XFER_REQUEST)
)
)
)
{
if (fwork != nil(FILE)) /* in case matched with scandir */
fclose(fwork);
scandir( NULL ); /* Reset directory search as well */
hostp = checkreal( rmtname );
checkref( hostp );
securep = GetSecurity( hostp );
if ( securep == NULL )
{
printmsg(0,"getsystem: system \"%s\" not defined in \
PERMISSIONS file", hostp->hostname);
return CONN_INITIALIZE;
}
memset( &remote_stats, 0, sizeof remote_stats);
return CONN_CALLUP; /* startup this system */
} else
return CONN_INITIALIZE; /* Look for next system to process */
} /*getsystem*/
/*--------------------------------------------------------------------*/
/* s y s e n d */
/* */
/* End UUCP session negotiation */
/*--------------------------------------------------------------------*/
CONN_STATE sysend()
{
char msg[80];
if (hostp->hstatus == inprogress)
hostp->hstatus = succeeded;
msg[1] = '\0';
wmsg("OOOOOO", TRUE);
if (rmsg(msg, TRUE, 5) == TIMEOUT)
goto hang;
hang:
wmsg("OOOOOO", TRUE);
return CONN_DROPLINE;
} /*sysend*/
/*
w m s g
write a ^P type msg to the remote uucp
*/
void wmsg(char *msg, const boolean synch)
{
if (synch)
swrite("\0\020", 2);
swrite(msg, strlen(msg));
if (synch)
swrite("\0", 1);
} /*wmsg*/
/*
r m s g
read a ^P msg from UUCP
*/
int rmsg(char *msg, const boolean synch, unsigned int msgtime)
{
int i;
static int max_len = 60;
char ch = '?'; /* Initialize to non-zero value */ /* ahd */
/*--------------------------------------------------------------------*/
/* flush until next ^P */
/*--------------------------------------------------------------------*/
if (synch == 1)
{
do {
if (sread(&ch, 1, msgtime) < 1)
return TIMEOUT;
} while ((ch & 0x7f) != '\020');
}
/*--------------------------------------------------------------------*/
/* Read until timeout, next newline, or we fill the input buffer */
/*--------------------------------------------------------------------*/
for (i = 0; (i < max_len) && (ch != '\0'); ) {
if (sread(&ch, 1, msgtime) < 1)
return TIMEOUT;
if ( synch == 2 )
swrite( &ch, 1);
ch &= 0x7f;
if (ch == '\r' || ch == '\n')
ch = '\0';
msg[i++] = ch;
}
msg[max_len - 1] = '\0';
return strlen(msg);
} /*rmsg*/
/*--------------------------------------------------------------------*/
/* s t a r t u p _ s e r v e r */
/* */
/* Exchange host and protocol information for a system we called */
/*--------------------------------------------------------------------*/
CONN_STATE startup_server()
{
char msg[80];
char *s;
/*--------------------------------------------------------------------*/
/* Handle the special case of '*' protocol, which is really our */
/* NBS time setting support */
/*--------------------------------------------------------------------*/
if (*protocols == '*')
{
if (nbstime())
{
didcall(rmtname);
hostp->hstatus = succeeded;
time( &hostp->hstats->lconnect );
}
return CONN_DROPLINE;
}
/*--------------------------------------------------------------------*/
/* Begin normal processing */
/*--------------------------------------------------------------------*/
if (rmsg(msg, TRUE, PROTOCOL_TIME) == TIMEOUT)
{
printmsg(1,"Startup: Timeout for first message");
return CONN_TERMINATE;
}
printmsg(2, "1st msg = %s", msg);
/*--------------------------------------------------------------------*/
/* The first message must begin with Shere */
/*--------------------------------------------------------------------*/
if (!equaln(msg,"Shere",5))
{
printmsg(1,"Startup: First message not Shere");
return CONN_TERMINATE;
}
/*--------------------------------------------------------------------*/
/* The host can send either a simple Shere, or Shere=hostname; */
/* we allow either. */
/*--------------------------------------------------------------------*/
if ((msg[5] == '=') && !equaln(&msg[6], rmtname, HOSTLEN))
{
printmsg(1,"Startup: Wrong host %s, expected %s",
&msg[6], rmtname);
hostp->hstatus = wrong_host;
return CONN_TERMINATE; /* wrong host */ /* ahd */
}
/* sprintf(msg, "S%.7s -Q0 -x%d", nodename, debuglevel); */
/* -Q0 -x16 remote debuglevel set */
sprintf(msg, "S%s", securep->myname );
wmsg(msg, TRUE);
/*--------------------------------------------------------------------*/
/* Second message is system is okay */
/*--------------------------------------------------------------------*/
if (rmsg(msg, TRUE, PROTOCOL_TIME) == TIMEOUT)
{
printmsg(1,"Startup: Timeout for second message");
return CONN_TERMINATE;
}
printmsg(2, "2nd msg = %s", msg);
if (!equaln(&msg[1], "OK", 2))
{
printmsg(1,"Unexpected second message: %s",&msg[1]);
return CONN_TERMINATE;
}
/*--------------------------------------------------------------------*/
/* Third message is protocol exchange */
/*--------------------------------------------------------------------*/
if (rmsg(msg, TRUE, PROTOCOL_TIME) == TIMEOUT)
return CONN_TERMINATE;
printmsg(2, "3rd msg = %s", msg);
if (*msg != 'P')
{
printmsg(1,"Unexpected third message: %s",&msg[1]);
return CONN_TERMINATE;
}
/*--------------------------------------------------------------------*/
/* Locate a common procotol */
/*--------------------------------------------------------------------*/
s = strpbrk( protocols, &msg[1] );
if ( s == NULL )
{
printmsg(1,"Startup: No common protocol");
wmsg("UN", TRUE);
return CONN_TERMINATE; /* no common protocol */
}
else {
sprintf(msg, "U%s", s);
wmsg(msg, TRUE);
}
setproto(*s);
/*--------------------------------------------------------------------*/
/* The connection is complete; report this and return to caller */
/*--------------------------------------------------------------------*/
printmsg(0,"%s connected to host %s at %ld bps using %c protocol",
nodename, rmtname, (long) GetSpeed() , *s);
hostp->hstatus = inprogress;
/* ahd */
didcall(rmtname);
return CONN_SERVER;
} /*startup_server*/
/*--------------------------------------------------------------------*/
/* s t a r t u p _ c l i e n t */
/* */
/* Setup a host connection with a system which has called us */
/*--------------------------------------------------------------------*/
CONN_STATE startup_client()
{
char tmp1[20], tmp2[20];
char msg[80];
/*--------------------------------------------------------------------*/
/* Challange the host calling in with the name defined for this */
/* login (if available) otherwise our regular node name. (It's */
/* a valid session if the securep pointer is NULL, but this is */
/* trapped below in the call to ValidateHost() */
/*--------------------------------------------------------------------*/
sprintf(msg, "Shere=%s", securep == NULL ?
nodename : securep->myname );
wmsg(msg, TRUE);
if (rmsg(msg, TRUE, PROTOCOL_TIME) == TIMEOUT)
return CONN_TERMINATE;
sscanf(&msg[1], "%s %s %s", rmtname, tmp1, tmp2);
sscanf(tmp2, "-x%d", &debuglevel);
printmsg(2, "debuglevel set to %d by remote", debuglevel);
printmsg(2, "1st msg from remote = %s", msg);
/*--------------------------------------------------------------------*/
/* Verify the remote host name is good */
/*--------------------------------------------------------------------*/
hostp = checkreal( rmtname );
if ( hostp == BADHOST )
{
if (anonymous != NULL)
{
hostp = checkreal( ANONYMOUS_HOST ); /* Find dummy entry */
if ( hostp == BADHOST ) /* Was it there? */
panic(); /* No --> Drop wing, run in
circles like sky is falling*/
if (!checktime( anonymous , 0)) /* Good time to call? */
{
wmsg("RLCK",TRUE);
return CONN_TERMINATE;
} /* if */
} /* if (anonymous != NULL) */
else {
wmsg("RYou are unknown to me",TRUE);
printmsg(0,"startup: Unknown host \"%s\"", rmtname);
return CONN_TERMINATE;
} /* else */
} /* if */
if ( !ValidateHost( rmtname ))
/* Wrong host for user? */
{ /* Yes --> Abort */
wmsg("RLOGIN",TRUE);
printmsg(0,"startup: Wrong host \"%s\", expected \"%s\"",
rmtname, hostp->hostname);
hostp->hstatus = wrong_host;
return CONN_TERMINATE;
} /* if */
strcpy(rmtname,hostp->hostname); /* Make sure we use the
full host name */
/*--------------------------------------------------------------------*/
/* If we must call the user back, do so */
/*--------------------------------------------------------------------*/
if (securep->callback)
{
wmsg("RCB",TRUE);
hostp->hstatus = callback_req;
return CONN_TERMINATE; /* Really more complex than this */
}
/*--------------------------------------------------------------------*/
/* The host name is good; get the protocol */
/*--------------------------------------------------------------------*/
wmsg("ROK", TRUE);
sprintf(msg, "P%s", PROTOS);
wmsg(msg, TRUE);
if (rmsg(msg, TRUE, PROTOCOL_TIME) == TIMEOUT)
return CONN_TERMINATE;
if (msg[0] != 'U')
{
printmsg(0,"Unexpected second message: %s", msg);
return CONN_TERMINATE;
}
if (strchr(PROTOS, msg[1]) == nil(char))
{
printmsg(0,"startup: Host does not support our protocols");
return CONN_TERMINATE;
}
setproto(msg[1]);
/*--------------------------------------------------------------------*/
/* Report that we connected to the remote host */
/*--------------------------------------------------------------------*/
printmsg(0,"%s called by %s at %ld bps using %c protocol",
nodename,
hostp->hostname,
(long) GetSpeed(),
msg[1]);
assert( hostp != BADHOST );
hostp->hstatus = inprogress;
time( &remote_stats.lconnect );
return CONN_CLIENT;
} /*startup_client*/
/*--------------------------------------------------------------------*/
/* s e t p r o t o */
/* */
/* set the protocol to be used */
/*--------------------------------------------------------------------*/
static void setproto(char wanted)
{
Proto *tproto;
for (tproto = Protolst;
tproto->type != '\0' && tproto->type != wanted;
tproto++) {
printmsg(3, "setproto: wanted '%c', have '%c'", wanted, tproto->type);
}
if (tproto->type == '\0') {
printmsg(0, "setproto: You said I have protocol '%c' but I cant find it!",
wanted);
panic();
}
getpkt = tproto->getpkt;
sendpkt = tproto->sendpkt;
openpk = tproto->openpk;
closepk = tproto->closepk;
rdmsg = tproto->rdmsg;
wrmsg = tproto->wrmsg;
eofpkt = tproto->eofpkt;
filepkt = tproto->filepkt;
} /*setproto*/
/*
s c a n d i r
Scan spooling directory for C.* files for the remote host
(rmtname)
Assumes the parameter remote is from static storage!
*/
XFER_STATE scandir(char *remote)
{
static DIR *dirp;
static char *saveremote = NULL;
static char remotedir[FILENAME_MAX];
struct direct *dp;
/*--------------------------------------------------------------------*/
/* Determine if we must restart the directory scan */
/*--------------------------------------------------------------------*/
if (fwork != NULL )
{
fclose( fwork );
fwork = NULL;
}
if ( (remote == NULL) || (saveremote == NULL ) ||
!equal(remote, saveremote) )
{
if ( saveremote != NULL ) /* Clean up old directory? */
{ /* Yes --> Do so */
closedir(dirp);
saveremote = NULL;
} /* if */
if ( remote == NULL ) /* Clean up only, no new search? */
return XFER_NOLOCAL; /* Yes --> Return to caller */
sprintf(remotedir,"%s/%.8s/C",spooldir,remote);
if ((dirp = opendir(remotedir)) == nil(DIR))
{
printmsg(2, "scandir: couldn't opendir() %s", remotedir);
return XFER_NOLOCAL;
} /* if */
saveremote = (char *) remote;
/* Flag we have an active search */
} /* if */
/*--------------------------------------------------------------------*/
/* Look for the next file in the directory */
/*--------------------------------------------------------------------*/
if ((dp = readdir(dirp)) != nil(struct direct))
{
sprintf(workfile, "%s/%s", remotedir, dp->d_name);
printmsg(5, "scandir: matched \"%s\"",workfile);
if ((fwork = FOPEN(workfile, "r", TEXT)) == nil(FILE))
{
printmsg(0,"scandir: open failed for %s",workfile);
saveremote = NULL;
return XFER_ABORT; /* Very bad, since we just read its
directory entry! */
}
else
return XFER_REQUEST; /* Return success */
}
/*--------------------------------------------------------------------*/
/* No hit; clean up after ourselves and return to the caller */
/*--------------------------------------------------------------------*/
printmsg(5, "scandir: \"%s\" not matched", remotedir);
closedir(dirp);
saveremote = NULL;
return XFER_NOLOCAL;
} /*scandir*/
/*
c a l l e d h o s t
reports true if a host has been called this run, otherwise FALSE
Drew Derbyshire, 18 August 1989
*/
boolean calledhost(char *hisremote)
{
struct HostTable *RmtEntry;
printmsg(8,"calledhost: Checking for host '%s'",hisremote);
RmtEntry = checkreal(hisremote);
if ( RmtEntry == BADHOST )
{
printmsg(0,"calledhost: Cannot find host \"%s\"",hisremote );
panic();
}
return RmtEntry->called;
}
/*
d i d c a l l
sets the flag tested by calledhost to true
Drew Derbyshire, 18 August 1989
*/
void didcall(char *hisremote)
{
struct HostTable *RmtEntry;
printmsg(8,"didcall: host '%s'",hisremote);
RmtEntry = checkreal(hisremote);
if ( RmtEntry == BADHOST )
{
printmsg(0,"calledhost: Cannot find host \"%s\"",hisremote );
panic();
}
RmtEntry->called = TRUE;
} /* didcall */